import { default as Web3 } from 'web3';
import { default as contract } from 'truffle-contract';
import resouceShare_artifacts from '../../build/contracts/ResouceShare.json';

var ResouceShare = contract(resouceShare_artifacts);

var ipfsAPI = require('ipfs-api');
// var fs = require('fs');
//实例化ipfs对象
var ipfs = ipfsAPI({ host: 'localhost', port: '5001', protocol: 'http' });

//定义web3对象，本地metamask链接账户
const adress = ethereum.request({ method: 'eth_requestAccounts' })
adress.then(
    val => {
        console.log("adress:");
        console.log(val[0]);
        web3.eth.defaultAccount = val[0];
    }
)

window.App = {
    start: function() {
        var self = this;
        //给当前合约对象set provider
        ResouceShare.setProvider(web3.currentProvider);
        renderStore();

        //对于文件的读取以及存取
        var readers;
        $("#product-image").change(event => {
            const input = event.target;
            readers = new window.FileReader();
            readers.readAsArrayBuffer(input.files[0]);
        });

        //add item to store
        $("#add-item-to-store").submit(function(event) {
            const req = $("#add-item-to-store").serialize();
            console.log("req:", req);
            let params = JSON.parse('{"' + req.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}');
            console.log("params: ", params);
            let decodedParams = {};
            Object.keys(params).forEach(key => {
                decodedParams[key] = decodeURIComponent(decodeURI(params[key]));
            });
            saveProduct(readers, decodedParams);
            event.preventDefault();
        });

        //产品细节展示
        if ($("#product-details").length > 0) {
            //This is product details page,后续可能报错，将id=>product-id
            let productId = new URLSearchParams(window.location.search).get('id');
            $("#revealing, #bidding").hide();
            renderProductDetails(productId);
        }

        //参与竞价
        $("#bidding").submit(event => {
            $("#msg").hide();
            let amount = $("#bid-amount").val();
            let sendAmount = $("#bid-send-amount").val();
            let secretText = $("#secret-text").val();
            let productId = $("#product-id").val();
            let sealedBid = web3.utils.sha3(web3.utils.fromWei(amount, 'ether').toString() + secretText);
            ResouceShare.deployed().then(i => {
                i.bid(parseInt(productId), sealedBid, { from: web3.eth.defaultAccount, value: web3.utils.toWei(sendAmount, 'ether'), gas: 3000000 }).then(res => {
                    $("#msg").html("Your bid has been successfully submitted!");
                    $("#msg").show();
                    console.log(res);
                });
            });
            event.preventDefault();
        });

        //揭示报价
        $("#revealing").submit(function(event) {
            $("#msg").hide();
            let amount = $("#actual-amount").val();
            let secretText = $("#reveal-secret-text").val();
            let productId = $("#product-id").val();
            ResouceShare.deployed().then(function(i) {
                i.revealBid(parseInt(productId), web3.utils.toWei(amount).toString(), secretText, { from: web3.eth.defaultAccount, gas: 3000000 }).then(
                    function(f) {
                        $("#msg").html("Your bid has been successfully revealed!");
                        $("#msg").show();
                        console.log(f)
                    });
            });
            event.preventDefault();
        });

    },
};

function renderStore() {
    ResouceShare.deployed().then(i => {
        //先写死，拿到指定产品的详情做渲染测试，后期在修改为iterate
        i.getProduct.call(1).then(function(p) {
            $("#product-list").append(buildProduct(p));
        });
        i.getProduct.call(2).then(function(p) {
            $("#product-list").append(buildProduct(p));
        });
        i.getProduct.call(3).then(function(p) {
            $("#product-list").append(buildProduct(p));
        });
    });
}

function renderProductDetails(productId) {
    ResouceShare.deployed().then(function(i) {
        i.getProduct.call(productId).then(function(p) {
            console.log(p);
            let content = "";
            ipfs.cat(p[4]).then(function(file) {
                content = file.toString();
                $("#product-desc").append("<div>" + content + "</div>");
            });

            $("#product-image").append("<img src='http://localhost:9001/ipfs/" + p[3] + "' width='250px' />");
            $("#product-price").html(displayPrice(p[7]));
            $("#product-name").html(p[1]);
            $("#product-auction-end").html(displayEndHours(p[6]));
            $("#product-id").val(p[0]);
            let currentTime = getCurrentTimeInSeconds();
            if (currentTime < p[6]) {
                $("#bidding").show();
            } else if (currentTime - (60) < p[6]) {
                $("#revealing").show();
            }
        })
    })
}

function getCurrentTimeInSeconds() {
    return Math.round(new Date() / 1000);
}

function displayPrice(amt) {
    return web3.utils.fromWei(amt, 'ether') + " ETH";
}

function displayEndHours(seconds) {
    let current_time = getCurrentTimeInSeconds()
    let remaining_seconds = seconds - current_time;

    if (remaining_seconds <= 0) {
        return "Auction has ended";
    }

    let days = Math.trunc(remaining_seconds / (24 * 60 * 60));
    remaining_seconds -= days * 24 * 60 * 60;

    let hours = Math.trunc(remaining_seconds / (60 * 60));
    remaining_seconds -= hours * 60 * 60;

    let minutes = Math.trunc(remaining_seconds / 60);
    remaining_seconds -= minutes * 60;

    if (days > 0) {
        return "Auction ends in " + days + " days, " + hours + ", hours, " + minutes + " minutes";
    } else if (hours > 0) {
        return "Auction ends in " + hours + " hours, " + minutes + " minutes ";
    } else if (minutes > 0) {
        return "Auction ends in " + minutes + " minutes ";
    } else {
        return "Auction ends in " + remaining_seconds + " seconds";
    }
}

function buildProduct(product) {
    let node = $("<div/>");
    node.addClass("col-sm-3 text-center col-margin-bottom-1");
    node.append("<a href='product.html?id=" + product[0] + "'><img src='http://localhost:9001/ipfs/" + product[3] + "'width = '150px' /></a>");
    node.append("<div>" + product[1] + "</div>");
    node.append("<div>" + product[2] + "</div>");
    node.append("<div>" + product[5] + "</div>");
    node.append("<div>" + product[6] + "</div>");
    node.append("<div>Wei: " + product[7] + "</div>");
    return node;
}

function saveImageOnIpfs(reader) {
    var buff = Buffer.from(reader.result);
    return new Promise((resolve, reject) => {
        ipfs.add(buff).then(res => {
            console.log("res: ", res);
            resolve(res[0].hash);
        }).catch(err => {
            console.error(err);
            reject(err);
        });
    });
}

function saveTextBlobOnIpfs(blob) {
    return new Promise((resolve, reject) => {
        let buffer = Buffer.from(blob, 'utf-8');
        ipfs.add(buffer).then(res => {
            console.log("res: ", res);
            resolve(res[0].hash);
        }).catch(err => {
            console.error(err);
            reject(err);
        });
    });
}

function saveProduct(reader, decodedParams) {
    let imageId, descId;
    saveImageOnIpfs(reader).then(id => {
        imageId = id;
        saveTextBlobOnIpfs(decodedParams["product-description"]).then(id => {
            descId = id;
            saveProductToBlockchain(decodedParams, imageId, descId);
        });
    });
}

function saveProductToBlockchain(params, imageId, descId) {
    console.log("params in save product: ", params);
    let auctionStartTime = Date.parse(params["product-auction-start"]) / 1000;
    let auctionEndTime = auctionStartTime + parseInt(params["product-auction-end"]) * 24 * 60 * 60;
    ResouceShare.deployed().then(i => {
        i.addProductTostore(params["product-name"], params["product-category"], imageId, descId, auctionStartTime, auctionEndTime, web3.utils.toWei(params["product-price"], 'ether'), parseInt(params["product-condition"]), { from: web3.eth.defaultAccount, gas: 3000000 }).then(res => {
            console.log(res);
            $("#msg").show();
            $("#msg").html("Your product was successfully added to your store!");
        });
    });
}

window.addEventListener('load', function() {
    if (typeof web3 !== 'undefined') {
        window.web3 = new Web3(web3.currentProvider);
    } else {
        window.web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
    }
    App.start();
});